home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch16 / Light4.frm (.txt) < prev    next >
Visual Basic Form  |  1999-06-28  |  35KB  |  1,017 lines

  1. VERSION 5.00
  2. Begin VB.Form frmLight4 
  3.    Appearance      =   0  'Flat
  4.    BackColor       =   &H00C0C0C0&
  5.    Caption         =   "Light4"
  6.    ClientHeight    =   5445
  7.    ClientLeft      =   1410
  8.    ClientTop       =   540
  9.    ClientWidth     =   7005
  10.    BeginProperty Font 
  11.       Name            =   "MS Sans Serif"
  12.       Size            =   8.25
  13.       Charset         =   0
  14.       Weight          =   700
  15.       Underline       =   0   'False
  16.       Italic          =   0   'False
  17.       Strikethrough   =   0   'False
  18.    EndProperty
  19.    ForeColor       =   &H80000008&
  20.    KeyPreview      =   -1  'True
  21.    LinkTopic       =   "Form1"
  22.    PaletteMode     =   1  'UseZOrder
  23.    ScaleHeight     =   5445
  24.    ScaleWidth      =   7005
  25.    Begin VB.Frame Frame2 
  26.       Caption         =   "Light Sources"
  27.       Height          =   615
  28.       Left            =   2520
  29.       TabIndex        =   11
  30.       Top             =   0
  31.       Width           =   4095
  32.       Begin VB.CheckBox chkLights 
  33.          Caption         =   "Blue"
  34.          Height          =   255
  35.          Index           =   3
  36.          Left            =   3120
  37.          TabIndex        =   15
  38.          Top             =   240
  39.          Width           =   855
  40.       End
  41.       Begin VB.CheckBox chkLights 
  42.          Caption         =   "Green"
  43.          Height          =   255
  44.          Index           =   2
  45.          Left            =   2160
  46.          TabIndex        =   14
  47.          Top             =   240
  48.          Width           =   855
  49.       End
  50.       Begin VB.CheckBox chkLights 
  51.          Caption         =   "Red"
  52.          Height          =   255
  53.          Index           =   1
  54.          Left            =   1200
  55.          TabIndex        =   13
  56.          Top             =   240
  57.          Width           =   855
  58.       End
  59.       Begin VB.CheckBox chkLights 
  60.          Caption         =   "White"
  61.          Height          =   255
  62.          Index           =   0
  63.          Left            =   240
  64.          TabIndex        =   12
  65.          Top             =   240
  66.          Value           =   1  'Checked
  67.          Width           =   855
  68.       End
  69.    End
  70.    Begin VB.Frame Frame1 
  71.       Caption         =   "Scenes"
  72.       Height          =   3855
  73.       Left            =   0
  74.       TabIndex        =   1
  75.       Top             =   0
  76.       Width           =   2415
  77.       Begin VB.OptionButton optSolid 
  78.          Caption         =   "Fine Sphere"
  79.          Height          =   255
  80.          Index           =   9
  81.          Left            =   240
  82.          TabIndex        =   16
  83.          Top             =   3480
  84.          Width           =   2055
  85.       End
  86.       Begin VB.OptionButton optSolid 
  87.          Caption         =   "6 Tetrahedra"
  88.          Height          =   255
  89.          Index           =   0
  90.          Left            =   240
  91.          TabIndex        =   10
  92.          Top             =   240
  93.          Width           =   2055
  94.       End
  95.       Begin VB.OptionButton optSolid 
  96.          Caption         =   "8 Cubes"
  97.          Height          =   255
  98.          Index           =   1
  99.          Left            =   240
  100.          TabIndex        =   9
  101.          Top             =   600
  102.          Width           =   2055
  103.       End
  104.       Begin VB.OptionButton optSolid 
  105.          Caption         =   "6 Octahedra"
  106.          Height          =   255
  107.          Index           =   2
  108.          Left            =   240
  109.          TabIndex        =   8
  110.          Top             =   960
  111.          Width           =   2055
  112.       End
  113.       Begin VB.OptionButton optSolid 
  114.          Caption         =   "6 Dodecahedra"
  115.          Height          =   255
  116.          Index           =   3
  117.          Left            =   240
  118.          TabIndex        =   7
  119.          Top             =   1320
  120.          Width           =   2055
  121.       End
  122.       Begin VB.OptionButton optSolid 
  123.          Caption         =   "6 Icosahedra"
  124.          Height          =   255
  125.          Index           =   4
  126.          Left            =   240
  127.          TabIndex        =   6
  128.          Top             =   1680
  129.          Width           =   2055
  130.       End
  131.       Begin VB.OptionButton optSolid 
  132.          Caption         =   "Platonic Solids"
  133.          Height          =   255
  134.          Index           =   5
  135.          Left            =   240
  136.          TabIndex        =   5
  137.          Top             =   2040
  138.          Width           =   2055
  139.       End
  140.       Begin VB.OptionButton optSolid 
  141.          Caption         =   "Stellate Octahedron"
  142.          Height          =   255
  143.          Index           =   6
  144.          Left            =   240
  145.          TabIndex        =   4
  146.          Top             =   2400
  147.          Width           =   2055
  148.       End
  149.       Begin VB.OptionButton optSolid 
  150.          Caption         =   "Coarse Sphere"
  151.          Height          =   255
  152.          Index           =   7
  153.          Left            =   240
  154.          TabIndex        =   3
  155.          Top             =   2760
  156.          Width           =   2055
  157.       End
  158.       Begin VB.OptionButton optSolid 
  159.          Caption         =   "Medium Sphere"
  160.          Height          =   255
  161.          Index           =   8
  162.          Left            =   240
  163.          TabIndex        =   2
  164.          Top             =   3120
  165.          Width           =   2055
  166.       End
  167.    End
  168.    Begin VB.PictureBox picCanvas 
  169.       AutoRedraw      =   -1  'True
  170.       Height          =   3615
  171.       Left            =   2520
  172.       ScaleHeight     =   237
  173.       ScaleMode       =   3  'Pixel
  174.       ScaleWidth      =   197
  175.       TabIndex        =   0
  176.       Top             =   720
  177.       Width           =   3015
  178.    End
  179. Attribute VB_Name = "frmLight4"
  180. Attribute VB_GlobalNameSpace = False
  181. Attribute VB_Creatable = False
  182. Attribute VB_PredeclaredId = True
  183. Attribute VB_Exposed = False
  184. Option Explicit
  185. ' Location of viewing eye.
  186. Private EyeR As Single
  187. Private EyeTheta As Single
  188. Private EyePhi As Single
  189. Private Const dtheta = PI / 20
  190. Private Const dphi = PI / 20
  191. Private Const Dr = 1
  192. ' Location of focus point.
  193. Private Const FocusX = 0#
  194. Private Const FocusY = 0#
  195. Private Const FocusZ = 0#
  196. Private Projector(1 To 4, 1 To 4) As Single
  197. Private Solids As Collection
  198. Private LightSources As Collection
  199. Private SelectedShape As Integer
  200. Private Const THE_AMBIENT_LIGHT = 50
  201. ' Specular reflection coefficients for all solids.
  202. Private Const SPEC_K = 0.5
  203. Private Const SPEC_N = 50
  204. ' Set this light source's Kdist and Rmin values.
  205. Private Sub ScaleIntensityForDepth(ByVal light As LightSource)
  206. Dim solid As Solid3d
  207. Dim Rmin As Single
  208. Dim Rmax As Single
  209. Dim new_rmin As Single
  210. Dim new_rmax As Single
  211.     Rmin = 1E+30
  212.     Rmax = -1E+30
  213.     For Each solid In Solids
  214.         solid.GetRminRmax new_rmin, new_rmax, _
  215.             light.X, light.Y, light.Z
  216.         If Rmin > new_rmin Then Rmin = new_rmin
  217.         If Rmax < new_rmax Then Rmax = new_rmax
  218.     Next solid
  219.     light.Rmin = Rmin
  220. '    light.Kdist = (Rmax - 5 * Rmin) / 4 ' Fade to 1/5.
  221.     light.Kdist = Rmax - 2 * Rmin ' Fade to 1/2.
  222. End Sub
  223. ' Set the light sources' Kdist and Rmin values.
  224. Private Sub ScaleLightSourcesForDepth()
  225. Dim light As LightSource
  226.     For Each light In LightSources
  227.         ScaleIntensityForDepth light
  228.     Next light
  229. End Sub
  230. ' Sort the solids in depth-sort order.
  231. Private Sub SortSolids()
  232. Dim solid As Solid3d
  233. Dim ordered_solids As Collection
  234. Dim besti As Integer
  235. Dim bestz As Single
  236. Dim newz As Single
  237. Dim i As Integer
  238.     ' Compute each solid's Zmax value.
  239.     For Each solid In Solids
  240.         solid.SetZmax
  241.     Next solid
  242.     ' Sort the objects by their Zmax values.
  243.     Set ordered_solids = New Collection
  244.     Do While Solids.Count > 0
  245.         ' Find the face with the smallest Zmax
  246.         ' left in the Faces collection.
  247.         besti = 1
  248.         bestz = Solids(1).zmax
  249.         For i = 2 To Solids.Count
  250.             newz = Solids(i).zmax
  251.             If bestz > newz Then
  252.                 besti = i
  253.                 bestz = newz
  254.             End If
  255.         Next i
  256.         ' Add the best object to the sorted list.
  257.         ordered_solids.Add Solids(besti)
  258.         Solids.Remove besti
  259.     Loop
  260.     ' Replace the Solids collection with the
  261.     ' ordered_solids collection.
  262.     Set Solids = ordered_solids
  263. End Sub
  264. ' Draw the data.
  265. Private Sub DrawData(ByVal pic As PictureBox)
  266. Dim solid As Solid3d
  267. Dim X As Single
  268. Dim Y As Single
  269. Dim Z As Single
  270. Dim S(1 To 4, 1 To 4) As Single
  271. Dim T(1 To 4, 1 To 4) As Single
  272. Dim ST(1 To 4, 1 To 4) As Single
  273. Dim PST(1 To 4, 1 To 4) As Single
  274.     ' Prevent overflow errors when drawing lines
  275.     ' too far out of bounds.
  276.     On Error Resume Next
  277.     ' Uncull the solids.
  278.     For Each solid In Solids
  279.         solid.Culled = False
  280.     Next solid
  281.     ' Cull backfaces.
  282.     m3SphericalToCartesian EyeR, EyeTheta, EyePhi, X, Y, Z
  283.     For Each solid In Solids
  284.         solid.Culled = False
  285.         solid.Cull X, Y, Z
  286.     Next solid
  287.     ' Scale and translate so it looks OK in pixels.
  288.     m3Scale S, 100, -100, 1
  289.     m3Translate T, pic.ScaleWidth / 2, pic.ScaleHeight / 2, 0
  290.     m3MatMultiplyFull ST, S, T
  291.     m3MatMultiplyFull PST, Projector, ST
  292.     ' Transform the solids and clip faces.
  293.     For Each solid In Solids
  294.         solid.ApplyFull PST
  295.         ' Clip faces behind the center of projection.
  296.         solid.ClipEye EyeR
  297.     Next solid
  298.     ' Sort the solids if necessary.
  299.     SortSolids
  300.     ' Set the light sources' Kdist and Rmin values
  301.     ' used to fade colors by distance. This should
  302.     ' happen after culling.
  303.     ScaleLightSourcesForDepth
  304.     ' Fill to cover hidden surfaces.
  305.     pic.FillStyle = vbFSSolid
  306.     ' Do not draw edge lines.
  307.     pic.DrawStyle = vbInvisible
  308.     ' Draw the solids.
  309.     pic.Cls
  310.     For Each solid In Solids
  311.         solid.Draw pic, LightSources, THE_AMBIENT_LIGHT, X, Y, Z
  312.     Next solid
  313.     pic.Refresh
  314. End Sub
  315. ' Make a sphere.
  316. Private Function Sphere(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal radius As Single, ByVal num_horizontal As Integer, ByVal num_vertical As Integer) As Solid3d
  317. Dim new_solid As Solid3d
  318. Dim T As Integer
  319. Dim theta1 As Single
  320. Dim theta2 As Single
  321. Dim dtheta As Single
  322. Dim P As Integer
  323. Dim phi1 As Single
  324. Dim phi2 As Single
  325. Dim dphi As Single
  326. Dim x11 As Single   ' xij: theta = i, phi = j
  327. Dim y11 As Single
  328. Dim z11 As Single
  329. Dim x12 As Single
  330. Dim y12 As Single
  331. Dim z12 As Single
  332. Dim x21 As Single
  333. Dim y21 As Single
  334. Dim z21 As Single
  335. Dim x22 As Single
  336. Dim y22 As Single
  337. Dim z22 As Single
  338. Dim R As Single
  339.     Set new_solid = New Solid3d
  340.     theta1 = 0
  341.     dtheta = 2 * PI / num_horizontal
  342.     For T = 1 To num_horizontal
  343.         theta2 = theta1 + dtheta
  344.         phi1 = -PI / 2
  345.         dphi = PI / num_vertical
  346.         x11 = 0
  347.         y11 = -radius
  348.         z11 = 0
  349.         x21 = 0
  350.         y21 = -radius
  351.         z21 = 0
  352.         For P = 1 To num_vertical
  353.             phi2 = phi1 + dphi
  354.             y12 = radius * Sin(phi2)
  355.             R = radius * Cos(phi2)
  356.             x12 = R * Cos(theta1)
  357.             z12 = R * Sin(theta1)
  358.             y22 = radius * Sin(phi2)
  359.             R = radius * Cos(phi2)
  360.             x22 = R * Cos(theta2)
  361.             z22 = R * Sin(theta2)
  362.             If P = 1 Then
  363.                 ' Bottom triangle.
  364.                 new_solid.AddFace _
  365.                     Cx + x11, Cy + y11, Cz + z11, _
  366.                     Cx + x12, Cy + y12, Cz + z12, _
  367.                     Cx + x22, Cy + y22, Cz + z22
  368.             ElseIf P = num_vertical Then
  369.                 ' Top triangle.
  370.                 new_solid.AddFace _
  371.                     Cx + x11, Cy + y11, Cz + z11, _
  372.                     Cx + x12, Cy + y12, Cz + z12, _
  373.                     Cx + x21, Cy + y21, Cz + z21
  374.             Else
  375.                 ' Middle rectangle.
  376.                 new_solid.AddFace _
  377.                     Cx + x11, Cy + y11, Cz + z11, _
  378.                     Cx + x12, Cy + y12, Cz + z12, _
  379.                     Cx + x22, Cy + y22, Cz + z22, _
  380.                     Cx + x21, Cy + y21, Cz + z21
  381.             End If
  382.             x11 = x12
  383.             y11 = y12
  384.             z11 = z12
  385.             x21 = x22
  386.             y21 = y22
  387.             z21 = z22
  388.             phi1 = phi2
  389.         Next P
  390.         theta1 = theta2
  391.     Next T
  392.     new_solid.IsConvex = True
  393.     new_solid.HideSurfaces = True
  394.     new_solid.SetDiffuseCoefficients 1#, 1#, 1#
  395.     new_solid.SetAmbientCoefficients 1#, 1#, 1#
  396.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  397.     Set Sphere = new_solid
  398. End Function
  399. Private Sub chkLights_Click(Index As Integer)
  400.     Screen.MousePointer = vbHourglass
  401.     DoEvents
  402.     CreateLightSources
  403.     DrawData picCanvas
  404.     picCanvas.SetFocus
  405.     Screen.MousePointer = vbDefault
  406. End Sub
  407. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  408.     Select Case KeyCode
  409.         Case vbKeyLeft
  410.             EyeTheta = EyeTheta - dtheta
  411.         
  412.         Case vbKeyRight
  413.             EyeTheta = EyeTheta + dtheta
  414.         
  415.         Case vbKeyUp
  416.             EyePhi = EyePhi - dphi
  417.         
  418.         Case vbKeyDown
  419.             EyePhi = EyePhi + dphi
  420.                 
  421.         Case Else
  422.             Exit Sub
  423.     End Select
  424.     Screen.MousePointer = vbHourglass
  425.     DoEvents
  426.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  427.     DrawData picCanvas
  428.     Screen.MousePointer = vbDefault
  429. End Sub
  430. Private Sub Form_Load()
  431.     ' Initialize the eye position.
  432.     EyeR = 10
  433.     EyeTheta = PI * 0.2
  434.     EyePhi = PI * 0.05
  435.     ' Initialize the projection transformation.
  436.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  437.     ' Start with the tetrahedron.
  438.     Show
  439.     CreateLightSources
  440.     optSolid(0).value = True
  441. End Sub
  442. ' Create the data.
  443. Private Sub CreateData()
  444.     ' Create the new Solids collection.
  445.     Set Solids = New Collection
  446.     ' Create the solids.
  447.     Select Case SelectedShape
  448.         Case 0  ' Tetrahedra.
  449.             Solids.Add Tetrahedron(0.75, 0.5 + 0, 0, 0.4)
  450.             Solids.Add Tetrahedron(0, 0.5 + 0.75, 0, 0.4)
  451.             Solids.Add Tetrahedron(0, 0.5 + 0, 0.75, 0.4)
  452.             Solids.Add Tetrahedron(-0.75, 0.5 + 0, 0, 0.4)
  453.             Solids.Add Tetrahedron(0, 0.5 + -0.75, 0, 0.4)
  454.             Solids.Add Tetrahedron(0, 0.5 + 0, -0.75, 0.4)
  455.         Case 1  ' Cubes.
  456.             Solids.Add Cube(0.5, 0.5, 0.5, 0.4)
  457.             Solids.Add Cube(0.5, 0.5, -0.5, 0.4)
  458.             Solids.Add Cube(0.5, -0.5, 0.5, 0.4)
  459.             Solids.Add Cube(-0.5, 0.5, 0.5, 0.4)
  460.             Solids.Add Cube(0.5, -0.5, -0.5, 0.4)
  461.             Solids.Add Cube(-0.5, 0.5, -0.5, 0.4)
  462.             Solids.Add Cube(-0.5, -0.5, 0.5, 0.4)
  463.             Solids.Add Cube(-0.5, -0.5, -0.5, 0.4)
  464.         Case 2  ' Octahedra.
  465.             Solids.Add Octahedron(0.75, 0, 0, 0.4)
  466.             Solids.Add Octahedron(0, 0.75, 0, 0.4)
  467.             Solids.Add Octahedron(0, 0, 0.75, 0.4)
  468.             Solids.Add Octahedron(-0.75, 0, 0, 0.4)
  469.             Solids.Add Octahedron(0, -0.75, 0, 0.4)
  470.             Solids.Add Octahedron(0, 0, -0.75, 0.4)
  471.         Case 3  ' Dodecahedra.
  472.             Solids.Add Dodecahedron(0.75, 0, 0, 0.3)
  473.             Solids.Add Dodecahedron(0, 0.75, 0, 0.3)
  474.             Solids.Add Dodecahedron(0, 0, 0.75, 0.3)
  475.             Solids.Add Dodecahedron(-0.75, 0, 0, 0.3)
  476.             Solids.Add Dodecahedron(0, -0.75, 0, 0.3)
  477.             Solids.Add Dodecahedron(0, 0, -0.75, 0.3)
  478.         Case 4  ' Icosahedra.
  479.             Solids.Add Icosahedron(0.75, 0, 0, 0.4)
  480.             Solids.Add Icosahedron(0, 0.75, 0, 0.4)
  481.             Solids.Add Icosahedron(0, 0, 0.75, 0.4)
  482.             Solids.Add Icosahedron(-0.75, 0, 0, 0.4)
  483.             Solids.Add Icosahedron(0, -0.75, 0, 0.4)
  484.             Solids.Add Icosahedron(0, 0, -0.75, 0.4)
  485.         Case 5  ' Platonic solids.
  486.             Solids.Add Tetrahedron(0, 0.6 + 0.75, 0, 0.4)
  487.             Solids.Add Cube(0.75, 0, 0, 0.6)
  488.             Solids.Add Octahedron(0, 0, 0.75, 0.5)
  489.             Solids.Add Dodecahedron(-0.75, 0, 0, 0.4)
  490.             Solids.Add Icosahedron(0, 0, -0.75, 0.5)
  491.         Case 6  ' Stellate octahedron.
  492.             MakeStellate8 0.75
  493.         Case 7  ' Coarse Sphere.
  494.             Solids.Add Sphere(0, 0, 0, 1, 10, 10)
  495.         Case 8  ' Medium Sphere.
  496.             Solids.Add Sphere(0, 0, 0, 1, 30, 30)
  497.         Case 9  ' Fine Sphere.
  498.             Solids.Add Sphere(0, 0, 0, 1, 100, 100)
  499.     End Select
  500. End Sub
  501. ' Create the light sources.
  502. Private Sub CreateLightSources()
  503. Dim light As LightSource
  504.     ' Create the new LightSources collection.
  505.     Set LightSources = New Collection
  506.     ' Create the light sources.
  507.     ' White.
  508.     If chkLights(0).value = vbChecked Then
  509.         Set light = New LightSource
  510.         LightSources.Add light
  511.         light.Initialize -300, 500, 1000, 200, 200, 200
  512.     End If
  513.     ' Red.
  514.     If chkLights(1).value = vbChecked Then
  515.         Set light = New LightSource
  516.         LightSources.Add light
  517.         light.Initialize -200, 200, 1000, 200, 0, 0
  518.     End If
  519.     ' Green.
  520.     If chkLights(2).value = vbChecked Then
  521.         Set light = New LightSource
  522.         LightSources.Add light
  523.         light.Initialize 300, -500, 300, 0, 200, 0
  524.     End If
  525.     ' Blue.
  526.     If chkLights(3).value = vbChecked Then
  527.         Set light = New LightSource
  528.         LightSources.Add light
  529.         light.Initialize 1000, 300, -300, 0, 0, 200
  530.     End If
  531. End Sub
  532. ' Make a stellate octahedron.
  533. Private Sub MakeStellate8(ByVal side_scale As Single)
  534. Dim new_solid As Solid3d
  535.     Set new_solid = New Solid3d
  536.     Solids.Add new_solid
  537.     new_solid.IsConvex = False
  538.     new_solid.HideSurfaces = True
  539.     new_solid.Stellate side_scale, _
  540.         0, side_scale, 0, _
  541.         0, 0, side_scale, _
  542.         side_scale, 0, 0
  543.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  544.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  545.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  546.     Set new_solid = New Solid3d
  547.     Solids.Add new_solid
  548.     new_solid.IsConvex = False
  549.     new_solid.HideSurfaces = True
  550.     new_solid.Stellate side_scale, _
  551.         0, side_scale, 0, _
  552.         side_scale, 0, 0, _
  553.         0, 0, -side_scale
  554.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  555.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  556.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  557.     Set new_solid = New Solid3d
  558.     Solids.Add new_solid
  559.     new_solid.IsConvex = False
  560.     new_solid.HideSurfaces = True
  561.     new_solid.Stellate side_scale, _
  562.         0, side_scale, 0, _
  563.         0, 0, -side_scale, _
  564.         -side_scale, 0, 0
  565.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  566.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  567.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  568.     Set new_solid = New Solid3d
  569.     Solids.Add new_solid
  570.     new_solid.IsConvex = False
  571.     new_solid.HideSurfaces = True
  572.     new_solid.Stellate side_scale, _
  573.         0, side_scale, 0, _
  574.         -side_scale, 0, 0, _
  575.         0, 0, side_scale
  576.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  577.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  578.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  579.     Set new_solid = New Solid3d
  580.     Solids.Add new_solid
  581.     new_solid.IsConvex = False
  582.     new_solid.HideSurfaces = True
  583.     new_solid.Stellate side_scale, _
  584.         0, -side_scale, 0, _
  585.         side_scale, 0, 0, _
  586.         0, 0, side_scale
  587.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  588.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  589.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  590.     Set new_solid = New Solid3d
  591.     Solids.Add new_solid
  592.     new_solid.IsConvex = False
  593.     new_solid.HideSurfaces = True
  594.     new_solid.Stellate side_scale, _
  595.         0, -side_scale, 0, _
  596.         0, 0, -side_scale, _
  597.         side_scale, 0, 0
  598.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  599.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  600.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  601.     Set new_solid = New Solid3d
  602.     Solids.Add new_solid
  603.     new_solid.IsConvex = False
  604.     new_solid.HideSurfaces = True
  605.     new_solid.Stellate side_scale, _
  606.         0, -side_scale, 0, _
  607.         -side_scale, 0, 0, _
  608.         0, 0, -side_scale
  609.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  610.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  611.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  612.     Set new_solid = New Solid3d
  613.     Solids.Add new_solid
  614.     new_solid.IsConvex = False
  615.     new_solid.HideSurfaces = True
  616.     new_solid.Stellate side_scale, _
  617.         0, -side_scale, 0, _
  618.         0, 0, side_scale, _
  619.         -side_scale, 0, 0
  620.     new_solid.SetDiffuseCoefficients 1#, 0.5, 1#
  621.     new_solid.SetAmbientCoefficients 1#, 0.5, 1#
  622.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  623. End Sub
  624. ' Make a dodecahedron.
  625. Private Function Dodecahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  626. Dim new_solid As Solid3d
  627. Dim theta1 As Single
  628. Dim theta2 As Single
  629. Dim s1 As Single
  630. Dim s2 As Single
  631. Dim c1 As Single
  632. Dim c2 As Single
  633. Dim M As Single
  634. Dim n As Single
  635. Dim S As Single
  636. Dim R As Single
  637. Dim A As Single
  638. Dim B As Single
  639. Dim C As Single
  640. Dim D As Single
  641. Dim H As Single
  642. Dim X As Single
  643. Dim Y As Single
  644. Dim y2 As Single
  645.     theta1 = PI * 0.4
  646.     theta2 = PI * 0.8
  647.     s1 = Sin(theta1)
  648.     c1 = Cos(theta1)
  649.     s2 = Sin(theta2)
  650.     c2 = Cos(theta2)
  651.     M = 1 - (2 - 2 * c1 - 4 * s1 * s1) / (2 * c1 - 2)
  652.     n = Sqr((2 - 2 * c1) - M * M) * (1 + (1 - c2) / (c1 - c2))
  653.     R = 2 / n * side_scale
  654.     S = R * Sqr(2 - 2 * c1)
  655.     A = R * s1
  656.     B = R * s2
  657.     C = R * c1
  658.     D = R * c2
  659.     H = R * (c1 - s1)
  660.     X = (R * R * (2 - 2 * c1) - 4 * A * A) / (2 * C - 2 * R)
  661.     Y = Sqr(S * S - (R - X) * (R - X))
  662.     y2 = Y * (1 - c2) / (c1 - c2)
  663.     Set new_solid = New Solid3d
  664.     new_solid.AddFace _
  665.         Cx + C, Cy + side_scale, Cz + -A, _
  666.         Cx + D, Cy + side_scale, Cz + -B, _
  667.         Cx + D, Cy + side_scale, Cz + B, _
  668.         Cx + C, Cy + side_scale, Cz + A, _
  669.         Cx + R, Cy + side_scale, Cz + 0
  670.     new_solid.AddFace _
  671.         Cx + C, Cy + side_scale, Cz + A, _
  672.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1, _
  673.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  674.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  675.         Cx + R, Cy + side_scale, Cz + 0
  676.     new_solid.AddFace _
  677.         Cx + C, Cy + side_scale, Cz + A, _
  678.         Cx + D, Cy + side_scale, Cz + B, _
  679.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2, _
  680.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  681.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1
  682.     new_solid.AddFace _
  683.         Cx + D, Cy + side_scale, Cz + B, _
  684.         Cx + D, Cy + side_scale, Cz + -B, _
  685.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, _
  686.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  687.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2
  688.     new_solid.AddFace _
  689.         Cx + D, Cy + side_scale, Cz + -B, _
  690.         Cx + C, Cy + side_scale, Cz + -A, _
  691.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1, _
  692.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  693.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, -X * c1
  694.     new_solid.AddFace _
  695.         Cx + C, Cy + side_scale, Cz + -A, _
  696.         Cx + R, Cy + side_scale, Cz + 0, _
  697.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  698.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  699.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1
  700.     ' Bottom.
  701.     new_solid.AddFace _
  702.         Cx + -D, Cy + -side_scale, Cz + -B, _
  703.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  704.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  705.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  706.         Cx + -D, Cy + -side_scale, Cz + B
  707.     new_solid.AddFace _
  708.         Cx + -D, Cy + -side_scale, Cz + B, _
  709.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  710.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1, _
  711.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  712.         Cx + -C, Cy + -side_scale, Cz + A
  713.     new_solid.AddFace _
  714.         Cx + -C, Cy + -side_scale, Cz + A, _
  715.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  716.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2, _
  717.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  718.         Cx + -R, Cy + -side_scale, Cz + 0
  719.     new_solid.AddFace _
  720.         Cx + -R, Cy + -side_scale, Cz + 0, _
  721.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  722.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, _
  723.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  724.         Cx + -C, Cy + -side_scale, Cz + -A
  725.     new_solid.AddFace _
  726.         Cx + -C, Cy + -side_scale, Cz + -A, _
  727.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  728.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1, _
  729.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  730.         Cx + -D, Cy + -side_scale, Cz + -B
  731.     new_solid.AddFace _
  732.         Cx + -D, Cy + -side_scale, Cz + -B, _
  733.         Cx + -D, Cy + -side_scale, Cz + B, _
  734.         Cx + -C, Cy + -side_scale, Cz + A, _
  735.         Cx + -R, Cy + -side_scale, Cz + 0, _
  736.         Cx + -C, Cy + -side_scale, Cz + -A
  737.     new_solid.IsConvex = True
  738.     new_solid.HideSurfaces = True
  739.     new_solid.SetDiffuseCoefficients 1#, 1#, 0.5
  740.     new_solid.SetAmbientCoefficients 1#, 1#, 0.5
  741.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  742.     Set Dodecahedron = new_solid
  743. End Function
  744. ' Make an icosahedron.
  745. Private Function Icosahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  746. Dim new_solid As Solid3d
  747. Dim theta1 As Single
  748. Dim theta2 As Single
  749. Dim s1 As Single
  750. Dim s2 As Single
  751. Dim c1 As Single
  752. Dim c2 As Single
  753. Dim A As Single
  754. Dim B As Single
  755. Dim C As Single
  756. Dim D As Single
  757. Dim H As Single
  758. Dim S As Single
  759. Dim R As Single
  760.     theta1 = PI * 0.4
  761.     theta2 = PI * 0.8
  762.     s1 = Sin(theta1)
  763.     c1 = Cos(theta1)
  764.     s2 = Sin(theta2)
  765.     c2 = Cos(theta2)
  766.     R = 2 / (2 * Sqr(1 - 2 * c1) + Sqr(3 / 4 * (2 - 2 * c1) - 2 * c2 - c2 * c2 - 1)) * side_scale
  767.     S = R * Sqr(2 - 2 * c1)
  768.     H = side_scale - Sqr(S * S - R * R)
  769.     A = R * s1
  770.     B = R * s2
  771.     C = R * c1
  772.     D = R * c2
  773.     ' Top.
  774.     Set new_solid = New Solid3d
  775.     new_solid.AddFace _
  776.         Cx + 0, Cy + side_scale, 0 + Cz, _
  777.         Cx + C, Cy + H, A + Cz, _
  778.         Cx + R, Cy + H, 0 + Cz
  779.     new_solid.AddFace _
  780.         Cx + 0, Cy + side_scale, 0 + Cz, _
  781.         Cx + R, Cy + H, 0 + Cz, _
  782.         Cx + C, Cy + H, -A + Cz
  783.     new_solid.AddFace _
  784.         Cx + 0, Cy + side_scale, 0 + Cz, _
  785.         Cx + C, Cy + H, -A + Cz, _
  786.         Cx + D, Cy + H, -B + Cz
  787.     new_solid.AddFace _
  788.         Cx + 0, Cy + side_scale, 0 + Cz, _
  789.         Cx + D, Cy + H, -B + Cz, _
  790.         Cx + D, Cy + H, B + Cz
  791.     new_solid.AddFace _
  792.         Cx + 0, Cy + side_scale, 0 + Cz, _
  793.         Cx + D, Cy + H, B + Cz, _
  794.         Cx + C, Cy + H, A + Cz
  795.     ' Upper Middle.
  796.     new_solid.AddFace _
  797.         Cx + R, Cy + H, 0 + Cz, _
  798.         Cx + C, Cy + H, A + Cz, _
  799.         Cx + -D, Cy + -H, B + Cz
  800.     new_solid.AddFace _
  801.         Cx + C, Cy + H, A + Cz, _
  802.         Cx + D, Cy + H, B + Cz, _
  803.         Cx + -C, Cy + -H, A + Cz
  804.     new_solid.AddFace _
  805.         Cx + D, Cy + H, B + Cz, _
  806.         Cx + D, Cy + H, -B + Cz, _
  807.         Cx + -R, Cy + -H, 0 + Cz
  808.     new_solid.AddFace _
  809.         Cx + D, Cy + H, -B + Cz, _
  810.         Cx + C, Cy + H, -A + Cz, _
  811.         Cx + -C, Cy + -H, -A + Cz
  812.     new_solid.AddFace _
  813.         Cx + C, Cy + H, -A + Cz, _
  814.         Cx + R, Cy + H, 0 + Cz, _
  815.         Cx + -D, Cy + -H, -B + Cz
  816.     ' Lower Middle.
  817.     new_solid.AddFace _
  818.         Cx + R, Cy + H, 0 + Cz, _
  819.         Cx + -D, Cy + -H, B + Cz, _
  820.         Cx + -D, Cy + -H, -B + Cz
  821.     new_solid.AddFace _
  822.         Cx + C, Cy + H, A + Cz, _
  823.         Cx + -C, Cy + -H, A + Cz, _
  824.         Cx + -D, Cy + -H, B + Cz
  825.     new_solid.AddFace _
  826.         Cx + D, Cy + H, B + Cz, _
  827.         Cx + -R, Cy + -H, 0 + Cz, _
  828.         Cx + -C, Cy + -H, A + Cz
  829.     new_solid.AddFace _
  830.         Cx + D, Cy + H, -B + Cz, _
  831.         Cx + -C, Cy + -H, -A + Cz, _
  832.         Cx + -R, Cy + -H, 0 + Cz
  833.     new_solid.AddFace _
  834.         Cx + C, Cy + H, -A + Cz, _
  835.         Cx + -D, Cy + -H, -B + Cz, _
  836.         Cx + -C, Cy + -H, -A + Cz
  837.     ' Bottom.
  838.     new_solid.AddFace _
  839.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  840.         Cx + -D, Cy + -H, B + Cz, _
  841.         Cx + -C, Cy + -H, A + Cz
  842.     new_solid.AddFace _
  843.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  844.         Cx + -C, Cy + -H, A + Cz, _
  845.         Cx + -R, Cy + -H, 0 + Cz
  846.     new_solid.AddFace _
  847.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  848.         Cx + -R, Cy + -H, 0 + Cz, _
  849.         Cx + -C, Cy + -H, -A + Cz
  850.     new_solid.AddFace _
  851.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  852.         Cx + -C, Cy + -H, -A + Cz, _
  853.         Cx + -D, Cy + -H, -B + Cz
  854.     new_solid.AddFace _
  855.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  856.         Cx + -D, Cy + -H, -B + Cz, _
  857.         Cx + -D, Cy + -H, B + Cz
  858.     new_solid.IsConvex = True
  859.     new_solid.HideSurfaces = True
  860.     new_solid.SetDiffuseCoefficients 0.5, 1#, 1#
  861.     new_solid.SetAmbientCoefficients 0.5, 1#, 1#
  862.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  863.     Set Icosahedron = new_solid
  864. End Function
  865. ' Make an octahedron.
  866. Private Function Octahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  867. Dim new_solid As Solid3d
  868.     ' Top.
  869.     Set new_solid = New Solid3d
  870.     new_solid.AddFace _
  871.         Cx + 0, Cy + side_scale, 0 + Cz, _
  872.         Cx + side_scale, Cy + 0, 0 + Cz, _
  873.         Cx + 0, Cy + 0, -side_scale + Cz
  874.     new_solid.AddFace _
  875.         Cx + 0, Cy + side_scale, 0 + Cz, _
  876.         Cx + 0, Cy + 0, -side_scale + Cz, _
  877.         Cx + -side_scale, Cy + 0, 0 + Cz
  878.     new_solid.AddFace _
  879.         Cx + 0, Cy + side_scale, 0 + Cz, _
  880.         Cx + -side_scale, Cy + 0, 0 + Cz, _
  881.         Cx + 0, Cy + 0, side_scale + Cz
  882.     new_solid.AddFace _
  883.         Cx + 0, Cy + side_scale, 0 + Cz, _
  884.         Cx + 0, Cy + 0, side_scale + Cz, _
  885.         Cx + side_scale, Cy + 0, 0 + Cz
  886.     ' Bottom.
  887.     new_solid.AddFace _
  888.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  889.         Cx + side_scale, Cy + 0, 0 + Cz, _
  890.         Cx + 0, Cy + 0, side_scale + Cz
  891.     new_solid.AddFace _
  892.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  893.         Cx + 0, Cy + 0, side_scale + Cz, _
  894.         Cx + -side_scale, Cy + 0, 0 + Cz
  895.     new_solid.AddFace _
  896.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  897.         Cx + -side_scale, Cy + 0, 0 + Cz, _
  898.         Cx + 0, Cy + 0, -side_scale + Cz
  899.     new_solid.AddFace _
  900.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  901.         Cx + 0, Cy + 0, -side_scale + Cz, _
  902.         Cx + side_scale, Cy + 0, 0 + Cz
  903.     new_solid.IsConvex = True
  904.     new_solid.HideSurfaces = True
  905.     new_solid.SetDiffuseCoefficients 0.5, 0.5, 1#
  906.     new_solid.SetAmbientCoefficients 0.5, 0.5, 1#
  907.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  908.     Set Octahedron = new_solid
  909. End Function
  910. ' Make a cube with the indicated center and
  911. ' side length.
  912. Private Function Cube(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  913. Dim new_solid As Solid3d
  914. Dim s2 As Single
  915.     s2 = side_scale / 2
  916.     Set new_solid = New Solid3d
  917.     ' Top.
  918.     new_solid.AddFace _
  919.         Cx + s2, Cy + s2, Cz + s2, _
  920.         Cx + s2, Cy + s2, Cz - s2, _
  921.         Cx - s2, Cy + s2, Cz - s2, _
  922.         Cx - s2, Cy + s2, Cz + s2
  923.     ' Positive X side.
  924.     new_solid.AddFace _
  925.         Cx + s2, Cy + s2, Cz + s2, _
  926.         Cx + s2, Cy - s2, Cz + s2, _
  927.         Cx + s2, Cy - s2, Cz - s2, _
  928.         Cx + s2, Cy + s2, Cz - s2
  929.     ' Positive Z side.
  930.     new_solid.AddFace _
  931.         Cx + s2, Cy + s2, Cz + s2, _
  932.         Cx - s2, Cy + s2, Cz + s2, _
  933.         Cx - s2, Cy - s2, Cz + s2, _
  934.         Cx + s2, Cy - s2, Cz + s2
  935.     ' Negative X side.
  936.     new_solid.AddFace _
  937.         Cx - s2, Cy - s2, Cz - s2, _
  938.         Cx - s2, Cy - s2, Cz + s2, _
  939.         Cx - s2, Cy + s2, Cz + s2, _
  940.         Cx - s2, Cy + s2, Cz - s2
  941.     ' Negative Z side.
  942.     new_solid.AddFace _
  943.         Cx - s2, Cy - s2, Cz - s2, _
  944.         Cx - s2, Cy + s2, Cz - s2, _
  945.         Cx + s2, Cy + s2, Cz - s2, _
  946.         Cx + s2, Cy - s2, Cz - s2
  947.     ' Bottom.
  948.     new_solid.AddFace _
  949.         Cx - s2, Cy - s2, Cz - s2, _
  950.         Cx + s2, Cy - s2, Cz - s2, _
  951.         Cx + s2, Cy - s2, Cz + s2, _
  952.         Cx - s2, Cy - s2, Cz + s2
  953.     new_solid.IsConvex = True
  954.     new_solid.HideSurfaces = True
  955.     new_solid.SetDiffuseCoefficients 0.5, 1#, 0.5
  956.     new_solid.SetAmbientCoefficients 0.5, 1#, 0.5
  957.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  958.     Set Cube = new_solid
  959. End Function
  960. ' Make a tetrahedron.
  961. Private Function Tetrahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  962. Dim new_solid As Solid3d
  963. Dim S As Single
  964. Dim A As Single
  965. Dim B As Single
  966. Dim C As Single
  967. Dim D As Single
  968.     S = Sqr(6) * side_scale
  969.     A = S / Sqr(3)
  970.     B = -A / 2
  971.     C = A * Sqr(2) - 1
  972.     D = S / 2
  973.     Set new_solid = New Solid3d
  974.     new_solid.AddFace _
  975.         Cx + 0, Cy + C, 0 + Cz, _
  976.         Cx + A, Cy + -1, 0 + Cz, _
  977.         Cx + B, Cy + -1, -D + Cz
  978.     new_solid.AddFace _
  979.         Cx + 0, Cy + C, 0 + Cz, _
  980.         Cx + B, Cy + -1, -D + Cz, _
  981.         Cx + B, Cy + -1, D + Cz
  982.     new_solid.AddFace _
  983.         Cx + 0, Cy + C, 0 + Cz, _
  984.         Cx + B, Cy + -1, D + Cz, _
  985.         Cx + A, Cy + -1, 0 + Cz
  986.     new_solid.AddFace _
  987.         Cx + A, Cy + -1, 0 + Cz, _
  988.         Cx + B, Cy + -1, D + Cz, _
  989.         Cx + B, Cy + -1, -D + Cz
  990.     new_solid.IsConvex = True
  991.     new_solid.HideSurfaces = True
  992.     new_solid.SetDiffuseCoefficients 1#, 0.5, 0.5
  993.     new_solid.SetAmbientCoefficients 1#, 0.5, 0.5
  994.     new_solid.SetSpecularCoefficients SPEC_K, SPEC_N
  995.     Set Tetrahedron = new_solid
  996. End Function
  997. ' Make the drawing areas as large as possible.
  998. Private Sub Form_Resize()
  999. Dim wid As Single
  1000. Dim hgt As Single
  1001.     wid = ScaleWidth - picCanvas.Left
  1002.     If wid < 120 Then wid = 120
  1003.     hgt = ScaleHeight - picCanvas.Top
  1004.     If hgt < 120 Then hgt = 120
  1005.     picCanvas.Move picCanvas.Left, picCanvas.Top, _
  1006.         wid, hgt
  1007. End Sub
  1008. Private Sub optSolid_Click(Index As Integer)
  1009.     Screen.MousePointer = vbHourglass
  1010.     DoEvents
  1011.     SelectedShape = Index
  1012.     CreateData
  1013.     DrawData picCanvas
  1014.     picCanvas.SetFocus
  1015.     Screen.MousePointer = vbDefault
  1016. End Sub
  1017.